home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1994
/
MacHack 1994.toast
/
MacHack™ 1987-1994
/
MacHack™ '87
/
DA's
/
Crabs+.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-01-18
|
7KB
|
232 lines
/* This is Crabs+, a rewriting of the famous Crabs DA into LightSpeedC.
It has been written with LsC2.01 by Daniel Ranson from the original
code in MacC. Contrary to the latter, this code will work on all
macs, and in all application that supports DAs.
To compile this, build a DA project with this file and MacTraps.
It should work with all versions of LsC.
My contribution, apart from the conversion to LsC, consists of
two tricks:
- The screen bitmap is found from the Window Manager port. This
is more reliable than using QuickDraw because: 1/ QuickDraw
globals are not DA globals. 2/ The application can choose where
it places QuickDraw globals. There are at least two favored
positions: -4(a5) and 0(a5). This is unreliable.
- When we CopyBits to the screen, the port is changed to a fake
port to prevent clipping. Without that, in the Finder with nothing
selected and the mouse outside any window, the crabs will only
draw OUTSIDE the windows.
There was no copyright notice in the original program I found, so
I don't add any. Feel free to dump this in your favorite trashcan
(real or iconic).
Daniel Ranson.
*/
/* Includes */
#include <QuickDraw.h>
#include <DeviceMgr.h>
/* Global variables */
short already_open = 0; /* 1 -> DA is already open */
DCtlPtr dce; /* device control entry */
BitMap grayMap, crabMap;
BitMap *screenPtr; /* Pointer to screen bitmap */
GrafPort fakePort;
Rect crabRect, topleftRect, drawRect;
Ptr grayPtr, crabPtr;
unsigned long grayBits[] = {
0xAAAA5555,
0xAAAA5555,
0xAAAA5555,
0xAAAA5555,
0xAAAA5555,
0xAAAA5555,
0xAAAA5555,
0xAAAA5555};
unsigned long crabBits[] = {
0xBEAA7755,
0xAAAA7F55,
0xBEAA7F55,
0xAAAA5555,
0xAAAA5555,
0xAAAA5555,
0xAAAA5555,
0xAAAA5555};
short crabCount, maxCrabs;
Point crabWhere[40];
#define MBarHeight *(short*)0xBAA
main(p, d, n)
cntrlParam *p; /* ==> parameter block */
DCtlPtr d; /* ==> device control entry */
short n; /* entry point selector */
{
/* check to make sure our data area was allocated */
if (d->dCtlStorage == 0) {
if (n == 0) { /* open */
SysBeep(3);
CloseDriver(d->dCtlRefNum);
}
return(0);
}
/* dispatch */
dce = d;
switch(n){
case 0: /* open */
doOpen();
break;
case 2: /* control */
if(p->csCode == accRun){ /* The real thing */
doRun();
}
break;
default: /* Ignore all prayers */
break;
}
/* done */
return(0); /* No Error */
}
/* Open routine */
doOpen()
{
register short whichCrab, i;
GrafPtr wPort, savedPort;
/* every time ... */
dce->dCtlFlags |= dNeedLock|dNeedTime;
dce->dCtlDelay = 10; /* Call every 10 ticks */
dce->dCtlEMask = 0; /* No events processed !! */
if(already_open)
return;
/* first time only ... */
already_open = 1;
/* Find screen bitmap through Window Manager port */
GetWMgrPort(&wPort);
screenPtr = &(wPort->portBits);
/*set up bitmaps for the screen, the crab, and the gray stuff the crabs
leave behind. The latter 2 bitmaps are bigger than they really
need to be because of the constraint that rowBytes must be even*/
grayPtr = NewPtr(32L);
crabPtr = NewPtr(32L);
SetRect(&crabRect,0,0,16,16);
SetRect(&topleftRect,0,0,8,8);
BlockMove(grayBits, grayPtr, 32L);
grayMap.baseAddr = grayPtr;
grayMap.rowBytes = 2;
grayMap.bounds = crabRect;
BlockMove(crabBits, crabPtr, 32L);
crabMap.baseAddr = crabPtr;
crabMap.rowBytes = 2;
crabMap.bounds = crabRect;
/*allocate a random # of crabs to starting positions down the left
edge of the screen, starting just below the menu bar */
maxCrabs = (screenPtr->bounds.bottom - screenPtr->bounds.top
- MBarHeight) / 8;
if(maxCrabs > 40) maxCrabs = 40;
for(i = 0, whichCrab = 0; i < maxCrabs; i++)
if(Random() & 0x0001){
crabWhere[whichCrab].h = screenPtr->bounds.left;
crabWhere[whichCrab].v = MBarHeight + i * 8;
whichCrab++;
}
crabCount = whichCrab; /* keep track of how many crabs were allocated */
/* Create a fake port to prevent CopyBits clipping */
GetPort(&savedPort);
OpenPort(&fakePort);
/* paste the top left corner of the crab bitmap ( i.e., the crab itself)
in each crab's starting position on the screen */
for(whichCrab = 0; whichCrab < crabCount; whichCrab++){
SetRect(&drawRect,
crabWhere[whichCrab].h,
crabWhere[whichCrab].v,
crabWhere[whichCrab].h + 8,
crabWhere[whichCrab].v + 8);
CopyBits(&crabMap, screenPtr,
&topleftRect, &drawRect, srcCopy, 0L);
}
SetPort(savedPort);
}
/* Run routine */
doRun(){
short offset,voffset,sign;
register short whichCrab;
GrafPtr savedPort;
GetPort(&savedPort);
SetPort(&fakePort);
/*first, replace all the current crabs with gray*/
for(whichCrab = 0; whichCrab < crabCount; whichCrab++){
SetRect(&drawRect,
crabWhere[whichCrab].h,
crabWhere[whichCrab].v,
crabWhere[whichCrab].h + 8,
crabWhere[whichCrab].v + 8);
CopyBits(&grayMap, screenPtr,
&topleftRect, &drawRect, srcCopy, 0L);
}
/* change each crab's position a little bit vertically,
somewhat more horizontally */
for(whichCrab = 0; whichCrab < crabCount; whichCrab++){
offset = (Random() & 0x0003); /* offset = 0,1,2, or 3*/
sign = ((Random() & 0x0001)? 1 : -1); /* + or - */
/* +/- 2,4,6, or 8 horiz */
crabWhere[whichCrab].h =
(crabWhere[whichCrab].h + sign * (2+2*offset));
/* Wraparound */
if(crabWhere[whichCrab].h + 8 >= screenPtr->bounds.right)
crabWhere[whichCrab].h = screenPtr->bounds.left;
else if(crabWhere[whichCrab].h < screenPtr->bounds.left)
crabWhere[whichCrab].h = screenPtr->bounds.right - 8;
voffset = (Random() & 0x0003);
switch(voffset){
case 0:
crabWhere[whichCrab].v = (crabWhere[whichCrab].v - 2);
/* Wraparound */
if(crabWhere[whichCrab].v + 8 >= screenPtr->bounds.bottom)
crabWhere[whichCrab].v = screenPtr->bounds.top;
else if(crabWhere[whichCrab].v < screenPtr->bounds.top)
crabWhere[whichCrab].v = screenPtr->bounds.bottom - 8;
break;
case 1:
case 2:
break;
case 3:
crabWhere[whichCrab].v = (crabWhere[whichCrab].v + 2)
% (screenPtr->bounds.bottom - screenPtr->bounds.top);
break;
default:
break;
}
}
/* redraw the little buggers */
for(whichCrab=0;whichCrab<crabCount;whichCrab++){
SetRect(&drawRect,
crabWhere[whichCrab].h,
crabWhere[whichCrab].v,
crabWhere[whichCrab].h + 8,
crabWhere[whichCrab].v + 8);
CopyBits(&crabMap, screenPtr, &topleftRect, &drawRect, srcCopy, 0L);
}
SetPort(savedPort);
}